home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.4 Applications 1997 August / SGI IRIX 6.4 Applications 1997 August.iso / dist / print.idb / usr / lib / lputil.z / lputil
Encoding:
Text File  |  1997-07-30  |  28.7 KB  |  1,111 lines

  1. #!/bin/sh
  2. #DEBUG
  3. #errlog=/var/spool/lp/log       # lp spooler error log file
  4. #exec 2>> $errlog
  5.  
  6. #
  7. #**************************************************************************
  8. #*
  9. #*           Copyright (c) 1993 Silicon Graphics, Inc.
  10. #*            All Rights Reserved
  11. #*
  12. #* RESTRICTED RIGHTS LEGEND:
  13. #*
  14. #* Use, duplication or disclosure by the Government is subject to
  15. #* restrictions as set forth in subdivision (c)(1)(ii) of the Rights in
  16. #* Technical Data and Computer Software clause at DFARS 52.227-7013,
  17. #* and/or in similar or successor clauses in the FAR, DOD or NASA FAR
  18. #* Supplement. Unpublished - rights reserved under the Copyright Laws of
  19. #* the United States. Contractor is SILICON GRAPHICS, INC., 2011 N.
  20. #* Shoreline Blvd., Mountain View, CA 94039-7311
  21. #**************************************************************************
  22. #*
  23. #* File: lputil
  24. #*
  25. #* $Revision: 1.67 $
  26. #*
  27. #* Description:
  28. #*    Printer utility script for use by administration tools.
  29. #*
  30. #*    This script is used by higher level commands and scripts to perform
  31. #*    lp system administration.  This script handles adding, deleting,
  32. #*    removing and typing of printers.
  33. #*
  34. #**************************************************************************
  35.  
  36. # Make sure we have a sane umask so that lp can read files we create
  37.  
  38. umask 022
  39.  
  40. # Reset path since we might spawn daemons
  41.  
  42. PATH=/usr/bsd:/bin:/usr/bin:/usr/sbin:/etc:/usr/etc
  43.  
  44. # Directories
  45.  
  46. X11_DIR=/usr/lib/X11
  47. OLD_SPOOL_DIR=/usr/spool/lp            # For 4.0 compatibility
  48. SPOOL_DIR=/var/spool/lp                # New location in 5.0
  49. REMOTE_MEMBER_DIR=$OLD_SPOOL_DIR/member        # For 4.0 compatibility
  50. REMOTE_INTER_DIR=$OLD_SPOOL_DIR/interface
  51. REMOTE_INTERGUI_DIR=$OLD_SPOOL_DIR/gui_interface
  52. REMOTE_APP_DEFS_DIR=$X11_DIR/app-defaults
  53. REMOTE_LANG_APP_DIR=$X11_DIR/$LANG/app-defaults
  54. POD_DIR=$SPOOL_DIR/pod
  55. MEMBER_DIR=$SPOOL_DIR/member
  56. MODELGUI_DIR=$SPOOL_DIR/gui_model
  57. INTERGUI_DIR=$SPOOL_DIR/gui_interface
  58. SETTINGS_DIR=$SPOOL_DIR/settings
  59. DATA_DIR=/usr/lib/print/data
  60. ACTIVEICON_DIR=$SPOOL_DIR/activeicons
  61. SPOOL_APP_DEFS_DIR=$SPOOL_DIR/app-defaults
  62. PSRIP_PARAMS_DIR=$SPOOL_DIR/psparams
  63. PRINT_DIR=/usr/lib/print
  64. SETDEVPERMS=$PRINT_DIR/setdevperms
  65.  
  66. PPD_MODEL_NAME=impressario_ppd_model
  67. PPD_MODEL_DIR=$SPOOL_DIR/PPD_model
  68. PPD_TO_POD=/usr/lib/print/ppdtopod
  69. PPD_PACK_FILES=/usr/lib/print/packppdfiles
  70. HAVE_PPD=0
  71. NUM_PPD_COLORS=1
  72. PPD_3COLOR=$SPOOL_DIR/PPD_model/impressario_ppd_common_3color.ppd
  73. PPD_4COLOR=$SPOOL_DIR/PPD_model/impressario_ppd_common_4color.ppd
  74.  
  75. # Global variables
  76.  
  77. REMOTE_LOGIN_ID=lp
  78. ACTIVEICON_TEMPLATE_FILENAME=$DATA_DIR/activeicon_template
  79.  
  80. #Binaries
  81.  
  82. UPDATE_IOPERM=/usr/lib/print/lpioupdate
  83.  
  84. #
  85. # This routine catches the return exit code of the previous command
  86. # and exits if there was any trouble.
  87. #
  88. rcexit()
  89. {
  90.     rc=$?
  91.     if [ $rc != 0 ]; then    # exit with an error code
  92.         exit $rc        # if the command failed
  93.     fi
  94. }
  95.  
  96. #
  97. # See if the number of installed printers is one
  98. # If so, make it the default printer
  99. #
  100.  
  101. selectSoloPrinterAsDefault() {
  102.     q="` lpstat -s | grep device | wc -l"
  103.     if [ $q = 1 ]; then
  104.            "` /usr/lib/lpadmin -d$nam"
  105.     fi
  106. }
  107.  
  108. #
  109. # This routine will create the file which is recognized by the desktop
  110. # as an active icon, and call tagprinter to put the right tag on it.
  111. #
  112. create_activeicon()
  113. {
  114.     # If we have no type, then give up and return
  115.     #
  116.     if [ "$rt" = "" ]; then
  117.     return 0
  118.     fi
  119.  
  120.     # If the icon directory doesn't exist, give up and return.
  121.     #
  122.     if [ ! -d $ACTIVEICON_DIR ]; then
  123.     return 0
  124.     fi
  125.  
  126.     # If the activeicon template file doesn't exist, give up and return.
  127.     #
  128.     if [ ! -f $ACTIVEICON_TEMPLATE_FILENAME ]; then
  129.     return 0
  130.     fi
  131.  
  132.     # First thing: install the activeicon file for printer $nam.
  133.     #
  134.     cp $ACTIVEICON_TEMPLATE_FILENAME $ACTIVEICON_DIR/$nam > /dev/null 2>&1
  135.  
  136.     # Make sure lp can write the file so it can tag it.
  137.     #
  138.     chown lp.lp $ACTIVEICON_DIR/$nam > /dev/null 2>&1
  139.  
  140.     # Set some defines to make tagging easier.
  141.     # The base (type of printer) tags
  142.     #
  143.     Dumb=66048            # 0x10200
  144.     DumbColor=66080        # 0x10220
  145.     Raster=66112        # 0x10240
  146.     ColorRaster=66144        # 0x10260
  147.     Plotter=66176        # 0x10280
  148.     PostScript=66208        # 0x102A0
  149.     ColorPostScript=66240    # 0x102C0
  150.     MonoPostScript=66272    # 0x102E0
  151.  
  152.     # And now the state modifiers for those type tags:
  153.     #
  154.     Networked=8            # 0x8
  155.  
  156.     # Set tag template based on printer type:
  157.     # Parse printer type and set the basetag.
  158.     #
  159.     case $rt in
  160.     Dumb|DUMB|dumb)
  161.         printertype=$Dumb
  162.         ;;
  163.     DumbColor|DUMBCOLOR|dumbcolor|Color|COLOR|color)
  164.         printertype=$DumbColor
  165.         ;;
  166.     Raster|RASTER|raster)
  167.         printertype=$Raster
  168.         ;;
  169.     ColorRaster|COLORRASTER|colorraster)
  170.         printertype=$ColorRaster
  171.         ;;
  172.     Plotter|PLOTTER|plotter)
  173.         printertype=$Plotter
  174.         ;;
  175.     PostScript|POSTSCRIPT|postscript)
  176.         printertype=$PostScript
  177.         ;;
  178.     ColorPostScript|COLORPOSTSCRIPT|colorpostscript)
  179.         printertype=$ColorPostScript
  180.         ;;
  181.     MonoPostScript|MONOPOSTSCRIPT|monopostscript)
  182.         printertype=$MonoPostScript
  183.         ;;     
  184.     *)    # XXX we just die silently if there's an unrecognized type.
  185.         # this is ok since we wouldn't know what to tag it anyways.
  186.         return 0
  187.         ;;
  188.     esac          
  189.  
  190.     # If we're a remote printer, add the "networked" modifier onto the tag
  191.     #
  192.     if [ -n "$rh" ]; then  
  193.     printertype=`expr $printertype + $Networked`
  194.     fi
  195.  
  196.     /usr/lib/print/tagprinter $nam $printertype > /dev/null 2>&1
  197.  
  198.     return 0
  199. }
  200.  
  201.  
  202. #
  203. # This routine will install the printer icons on the desktop
  204. #
  205. install_icon()
  206. {
  207.     # OK, first create the installed printer active icon file
  208.     # which will be installed into the desktop.
  209.     #
  210.     create_activeicon
  211.  
  212.     return 0
  213. }
  214.  
  215. #
  216. # This function creates a number of printing support directories
  217. #
  218. create_support_dirs()
  219. {
  220.     # Create a printer options settings directory for the printer
  221.     #
  222.     if [ ! -d "$SETTINGS_DIR" ]; then
  223.     mkdir -p $SETTINGS_DIR
  224.         chmod 755 $SETTINGS_DIR
  225.         chown lp.sys $SETTINGS_DIR
  226.     fi
  227.     if [ ! -d "$SETTINGS_DIR/$nam" ]; then
  228.         mkdir $SETTINGS_DIR/$nam
  229.         chmod 1777 $SETTINGS_DIR/$nam
  230.         chown lp.sys $SETTINGS_DIR/$nam
  231.     fi
  232.  
  233.     # Create a graphical options interface directory
  234.     #
  235.     if [ ! -d "$INTERGUI_DIR" ]; then
  236.     mkdir -p $INTERGUI_DIR         
  237.     chmod 755 $INTERGUI_DIR
  238.     chown lp.sys $INTERGUI_DIR
  239.     fi
  240.     if [ ! -d "$INTERGUI_DIR/ELF" ]; then
  241.     mkdir $INTERGUI_DIR/ELF         
  242.     chmod 755 $INTERGUI_DIR/ELF
  243.     chown lp.sys $INTERGUI_DIR/ELF
  244.     fi
  245.  
  246.     # Create a POD directory
  247.     #
  248.     if [ ! -d "$POD_DIR" ]; then
  249.     mkdir -p $POD_DIR
  250.     chmod 755 $POD_DIR
  251.     chown lp.sys $POD_DIR
  252.     fi
  253.  
  254.     return 0
  255. }
  256.  
  257.  
  258. #
  259. # This function installs the Printer Option Panel program
  260. # (a.k.a. graphical model file) if it is available
  261. #
  262. install_guimodel()
  263. {
  264.     # First install the gui model program
  265.  
  266.     # If this is a network printer we copy the graphical options
  267.     # panel from the host gui interface dir to the client 
  268.     # interface dir. We save some space by linking the program
  269.     # if the client and server are the same machine.
  270.     #
  271.     if [ -n "$rh" ]; then
  272.     if [ "$rh" = "`/usr/bsd/hostname`" ]; then
  273.            if [ -x $INTERGUI_DIR/ELF/$rp.gui ]; then
  274.             ln -s $INTERGUI_DIR/ELF/$rp.gui $INTERGUI_DIR/ELF/$nam.gui
  275.        fi
  276.        if [ -x $INTERGUI_DIR/$rp.gui ]; then
  277.                 ln -s $INTERGUI_DIR/$rp.gui $INTERGUI_DIR/$nam.gui
  278.        fi
  279.     else
  280.         rcp $REMOTE_LOGIN_ID@$rh:$REMOTE_INTERGUI_DIR/ELF/$rp.gui \
  281.             $INTERGUI_DIR/ELF/$nam.gui 2>/dev/null
  282.         if [ $? -ne 0 ]; then
  283.             rcp $REMOTE_LOGIN_ID@$rh:$REMOTE_INTERGUI_DIR/$rp.gui \
  284.                 $INTERGUI_DIR/$nam.gui 2>/dev/null
  285.         fi
  286.     fi
  287.     else
  288.     # If the printer is local make links instead of copying,
  289.     # to save some space.
  290.     #
  291.         if [ -x $MODELGUI_DIR/ELF/$mod.gui ]; then
  292.         ln -s $MODELGUI_DIR/ELF/$mod.gui $INTERGUI_DIR/ELF/$nam.gui
  293.         else
  294.             if [ "$HAVE_PPD" = "1" ]; then
  295.                 # For PPD there may not be a PPD name $nam.gui since we have
  296.                 # a general purpose PPD GUI that works for many GUIs.
  297.                 # Use this if a specific PPD GUI is not found
  298.                 if [ -x $MODELGUI_DIR/ELF/$PPD_MODEL_NAME.gui ]; then
  299.                     ln -s $MODELGUI_DIR/ELF/$PPD_MODEL_NAME.gui \
  300.                           $INTERGUI_DIR/ELF/$nam.gui
  301.                 fi
  302.             fi
  303.  
  304.     fi
  305.     fi
  306.  
  307.     # Now install the app-defaults
  308.  
  309.     # If this is a network printer we need to copy the graphical
  310.     # options panel app-defaults file to the spooling system
  311.     # app-defaults subdir.
  312.     #
  313.     if [ -n "$rh" ]; then
  314.     # Parse the interface file on the remote machine for the
  315.     # class name of the options panel.
  316.     #
  317.     guiclass=`rsh $rh -n -l $REMOTE_LOGIN_ID \
  318.         "/bin/sh -c \"egrep '^GUI_CLASS' $REMOTE_INTER_DIR/$rp\"" \
  319.         2>/dev/null`
  320.     if [ \( $? -eq 0 \) -a \( -n "$guiclass" \) ]; then
  321.         guiclass=`expr "$guiclass" : '^GUI_CLASS=\(.*\)'`
  322.  
  323.         # If we have a GUI class name...
  324.         #
  325.         if [ -n "$guiclass" ]; then
  326.         # Create the app-defaults subdir
  327.         #
  328.             if [ ! -d "$SPOOL_APP_DEFS_DIR" ]; then
  329.             mkdir -p $SPOOL_APP_DEFS_DIR
  330.                 chmod 755 $SPOOL_APP_DEFS_DIR
  331.                 chown lp.sys $SPOOL_APP_DEFS_DIR
  332.         fi
  333.             if [ ! -d "$SPOOL_APP_DEFS_DIR/$nam" ]; then
  334.                 mkdir $SPOOL_APP_DEFS_DIR/$nam
  335.                 chmod 755 $SPOOL_APP_DEFS_DIR/$nam
  336.                 chown lp.sys $SPOOL_APP_DEFS_DIR/$nam
  337.             fi
  338.  
  339.         # Copy the app-defaults file from the remote host
  340.         # to the spooler app-defaults subdir. Note that
  341.         # if LANG is set and is something other than "C"
  342.         # we copy over that app-default file.
  343.         #
  344.         apprcp=1
  345.         if [ \( "$LANG" != "" \) -a \( "$LANG" != "C" \) ]; then
  346.                 rcp $REMOTE_LOGIN_ID@$rh:$REMOTE_LANG_APP_DIR/$guiclass \
  347.                 $SPOOL_APP_DEFS_DIR/$nam/$guiclass 2>/dev/null
  348.             apprcp=$?
  349.         fi
  350.         if [ $apprcp -ne 0 ]; then
  351.                 rcp $REMOTE_LOGIN_ID@$rh:$REMOTE_APP_DEFS_DIR/$guiclass \
  352.                     $SPOOL_APP_DEFS_DIR/$nam/$guiclass 2>/dev/null
  353.         fi
  354.         fi
  355.     fi
  356.     fi
  357.  
  358.     return 0
  359. }
  360.  
  361.  
  362. #
  363. # This function installs the POD files. It is the caller's responsibilty
  364. # to ensure that the printer is local
  365. #
  366. install_pod()
  367. {
  368.     # Install the POD files for a local printer. Notice that we
  369.     # do a straight copy of the status and log files but the config
  370.     # file is copied by nawk which edits the 'Port Path' entry to
  371.     # contain the device port pathname.  We also handle some special 
  372.     # files for PPD drivers here.
  373.     #
  374.     if [ -d $DATA_DIR ]; then
  375.  
  376.         if [ "$HAVE_PPD" = "1" ]; then
  377.          
  378.            # PPD file.  
  379.            if [ -d $PPD_MODEL_DIR ]; then
  380.  
  381.                # Parse the PPD file and build the POD
  382.                # files on the fly since the features of the printer vary
  383.                # (the POD file describes the printer's features).
  384.  
  385.                if [ -x $PPD_TO_POD ]; then
  386.                    $PPD_TO_POD $mod $PPD_MODEL_DIR/$ppd_name
  387.                    rcexit
  388.                fi
  389.               
  390.                # We add our own general purpose options for PPD drivers. 
  391.                # This varies if the pritner is a monochrome, 3 color (rgb), 
  392.                # or four color device.   Default is monochrome.  If it is 
  393.                # 3 or 4 create a link in /var/spool/lp/PPD_model to
  394.                # impressario_ppd_common_3color.ppd or 
  395.                # impressario_ppd_common_4color.ppd.  The linked file is
  396.                # "<ppdname>.extension.ppd" which packppdfiles will know
  397.                # to use.
  398.  
  399.                if [ "$NUM_PPD_COLORS" != "1" ]; then
  400.                   name="`echo "$ppd_name" | sed 's/\.ppd/\.extension\.ppd/'`"
  401.                   if [ ! -f $PPD_MODEL_DIR/$name ]; then
  402.                      if [ "$NUM_PPD_COLORS" = "3" ]; then
  403.                         if [ -f $PPD_3COLOR ]; then
  404.                            ln -s $PPD_3COLOR $PPD_MODEL_DIR/$name 
  405.                         fi
  406.                      else
  407.                         if [ -f $PPD_4COLOR ]; then
  408.                            ln -s $PPD_4COLOR $PPD_MODEL_DIR/$name 
  409.                         fi 
  410.                      fi
  411.                   fi 
  412.  
  413.                fi 
  414.  
  415.                # This code creats the ~lp/app-defaults/<printername> file
  416.                # for PPDs.  Differs from other in that it contains PPDs
  417.                # and resource files all packed together.  They are unpacked 
  418.                # by the PPD GUI. We do this because 5.3 clients only copy
  419.                # over one file and we have to "pack" in the PPD files
  420.                # to get them over to the 5.3 client.
  421.               
  422.                if [ -x $PPD_PACK_FILES ]; then
  423.  
  424.                    # Create working dir because packppdfiels won't.
  425.  
  426.                    if [ ! -d "$SPOOL_APP_DEFS_DIR/$nam" ]; then
  427.                        mkdir $SPOOL_APP_DEFS_DIR/$nam
  428.                        chmod 755 $SPOOL_APP_DEFS_DIR/$nam
  429.                        chown lp.sys $SPOOL_APP_DEFS_DIR/$nam
  430.                    fi
  431.  
  432.                    $PPD_PACK_FILES $ppd_name $nam
  433.                    rcexit
  434.                fi
  435.  
  436.            fi
  437.         fi
  438.  
  439.     if [ -f $DATA_DIR/$mod.status ]; then 
  440.             cp $DATA_DIR/$mod.status $POD_DIR/$nam.status 2>/dev/null
  441.         rcexit
  442.         chown lp.lp $POD_DIR/$nam.status
  443.         chmod 0644 $POD_DIR/$nam.status
  444.     fi
  445.     if [ -f $DATA_DIR/$mod.config ]; then 
  446.         nawk -F\| '{
  447.         if ($1 ~ /^[ ]*Port[ ]+Path/) {
  448.             printf("%s| %s\n", $1, portdev)
  449.         } else {
  450.             printf("%s\n", $0)
  451.         }
  452.         }' portdev=$dev $DATA_DIR/$mod.config > \
  453.                     $POD_DIR/$nam.config 2>/dev/null
  454.         rcexit
  455.         chown lp.lp $POD_DIR/$nam.config
  456.         chmod 0644 $POD_DIR/$nam.config
  457.     fi
  458.     if [ -f $DATA_DIR/$mod.log ]; then 
  459.             cp $DATA_DIR/$mod.log $POD_DIR/$nam.log 2>/dev/null
  460.         rcexit
  461.         chown lp.lp $POD_DIR/$nam.log
  462.         chmod 0644 $POD_DIR/$nam.log
  463.     fi
  464.     fi
  465.  
  466.     return 0
  467. }
  468.  
  469.  
  470. #
  471. # Remove the active icon file for a printer.  This is separated from
  472. # remove_impressario because when changing connection (lputil replace)
  473. # the printer manager gets really messed up if the icon is removed.
  474. #
  475. remove_activeicon()
  476. {
  477.     # Remove the active icon.
  478.     #
  479.     rm -f $ACTIVEICON_DIR/$nam
  480. }
  481.  
  482. #
  483. # Change the permissions on the device as specified in the config file.
  484. # We do this because SCSI printers have fake devices for lpsched to
  485. # open, but actually use a different device for printing.  This whole
  486. # mess should be fixed.
  487. #
  488. fix_real_device()
  489. {
  490.     if [ -f $POD_DIR/$nam.config ]
  491.     then
  492.         real_device=`nawk -F\| '/^[ ]*Port[ ]+Path/ {
  493.         if (match($2, /[^ ]+/)) {
  494.         device = substr($2, RSTART, RLENGTH);
  495.         printf("%s", device);
  496.         }
  497.         exit
  498.         }' $POD_DIR/$nam.config 2>/dev/null`
  499.  
  500.         # If the printer was local and there are no other printers
  501.         # connected to this port, change the owner to root.sys and
  502.         # the permissions to defaults they are shipped with.
  503.     
  504.         if [ -n "$real_device" -a "$real_device" != "$dev" ]
  505.         then
  506.             mv $POD_DIR/$nam.config $POD_DIR/$nam.configtemp
  507.             grep "$real_device" $POD_DIR/*.config > /dev/null 2>&1
  508.             if [ $? != 0 ]; then
  509.               chmod 0600 $real_device
  510.            chown root.sys $real_device
  511.                #Update /etc/ioperms file by remving entry (see ioconfig(1M))
  512.                $SETDEVPERMS -d "$real_device 0600 lp sys"
  513.             fi
  514.             mv $POD_DIR/$nam.configtemp $POD_DIR/$nam.config
  515.         fi
  516.     fi
  517. }
  518.  
  519. #
  520. # This routine would remove the GUI interface files and
  521. # printer database file while removing an existing printer.
  522. #
  523. remove_impressario()
  524. {
  525.     # Remove the printer options settings directory
  526.     #
  527.     rm -rf $SETTINGS_DIR/$nam
  528.  
  529.     # Remove the graphical options panel
  530.     #
  531.     rm -f $INTERGUI_DIR/ELF/$nam.gui
  532.     rm -f $INTERGUI_DIR/$nam.gui
  533.  
  534.     # Remove the graphical options panel app-defaults
  535.     #
  536.     rm -rf $SPOOL_APP_DEFS_DIR/$nam
  537.  
  538.     # Remove the POD files
  539.     #
  540.     if [ -d $POD_DIR ]; then
  541.     fix_real_device
  542.         rm -f $POD_DIR/$nam.status
  543.         rm -f $POD_DIR/$nam.config 
  544.         rm -f $POD_DIR/$nam.log
  545.     fi
  546.   
  547.     # Remove the psrip paramaters directory for the printer
  548.     #
  549.     if [ -d $PSRIP_PARAMS_DIR/$nam ]; then
  550.        rm -rf $PSRIP_PARAMS_DIR/$nam
  551.     fi
  552.  
  553.     return 0
  554.  
  555. }
  556.  
  557. #
  558. # Remove a printer, including all the impressario stuff.
  559. #
  560. remove_printer()
  561. {
  562.     nam=$1
  563.     # Cancel any outstanding print requests
  564.     #
  565.     cancel `lpstat -o$nam | awk '{ print $1 }'` >/dev/null 2>&1
  566.  
  567.     # Get the device pahtname from the member file
  568.     #
  569.     dev=`cat $MEMBER_DIR/$nam 2> /dev/null`
  570.  
  571.     # Remove the printer
  572.     #
  573.     /usr/lib/lpadmin -x$nam
  574.     rc=$?
  575.  
  576.     if [ "$rc" != 0 ]; then
  577.         exit $rc
  578.     fi
  579.  
  580.     # If the printer was local and there are no other printers
  581.     # connected to this port, change the owner to root.sys and
  582.     # the permissions to defaults they are shipped with.
  583.     #
  584.     if [ \( -n "$dev" \) -a \( "$dev" != "/dev/null" \) ]; then
  585.         grep "$dev" $MEMBER_DIR/* > /dev/null 2>&1
  586.         if [ $? != 0 ]; then
  587.            chmod 0666 $dev
  588.            chown root.sys $dev
  589.            # For 6.4+ update /etc/ioperms file (see ioconfig(1M)) by
  590.            # removing this line
  591.            $SETDEVPERMS -d "$dev 0600 lp sys"
  592.         fi
  593.     fi
  594.  
  595.     # Old style printers had "/dev/printername" linked to their
  596.     # device.
  597.     #
  598.     if [ -f /dev/$nam ]; then
  599.         rm -f /dev/$nam
  600.     fi
  601.  
  602.     # Remove all the Impressario files.
  603.     #
  604.     remove_impressario
  605.     remove_activeicon
  606. }
  607.  
  608. #
  609. # Trap handler for when we have a problem installing
  610. #
  611. install_error()
  612. {
  613.     set +e  
  614.     trap '' 0 1 2 3 15
  615.     echo "Error installing printer '$1'" 1>&2
  616.     remove_printer $1
  617.     exit 1
  618. }
  619.  
  620. #
  621. # This routine will install the GUI model files and printer 
  622. # database files while adding a new printer.
  623. #
  624. install_impressario()
  625. {
  626.     # If anything goes wrong with impr stuff, abort
  627.     set -e
  628.     trap 'install_error $nam' 0 1 2 3 15
  629.  
  630.     # Now install the printer's active icon in the desktop.
  631.     #
  632.     install_icon
  633.  
  634.     # Create the printing support directories
  635.     #
  636.     create_support_dirs
  637.  
  638.     # If the printer is local install the POD files
  639.     #
  640.     if [ -z "$rh" ]; then
  641.     install_pod
  642.     fi
  643.  
  644.     #
  645.     # Remove error handling, because install_guimodel uses non-zero
  646.     # exit status to test existence of remote gui modelf files.  That
  647.     # code shouldn't ever be used anymore because of the "addnet"
  648.     # command, but it's still there so it should still work
  649.     #
  650.  
  651.     set +e 
  652.     trap '' 0 1 2 3 15
  653.  
  654.     # Install the graphical options panel
  655.     #
  656.     install_guimodel
  657.  
  658.     return 0
  659. }
  660.  
  661. #########################################################################
  662. #
  663. # Main program
  664. #
  665.  
  666. #
  667. # Start in a base directory
  668. #
  669. cd $SPOOL_DIR
  670.  
  671. #
  672. # Pick the primary function we are to perform
  673. #
  674. case $1 in
  675.     getinfo)
  676.     #
  677.     # getinfo <printername>
  678.     #
  679.     # This option is used to find various pieces of information
  680.     # about an installed printer.  The output format is multilple
  681.     # lines of keyword / value pairs separated by "="
  682.     #
  683.     shift
  684.     nam=$1
  685.     if [ -z "$nam" ]; then
  686.         echo "No printer name was specified." 1>&2
  687.         exit 1
  688.     fi
  689.     i=$nam
  690.     if [ -r class/$i ]; then
  691.         # If <printername> is a class, use the first member of the class.
  692.         #
  693.         i=`line < class/$i`
  694.     fi
  695.     cd interface
  696.     if [ ! -f $i ]; then
  697.         echo "non-existent" 1>&2
  698.         exit 2
  699.     else
  700.         egrep \
  701.         "^NAME=|^TYPE=|^HOSTNAME=|^HOSTPRINTER=|^BAUDRATE=|^STTYPARAMS=" $i
  702.         exit $?
  703.     fi
  704.     ;;
  705.     list)
  706.     /usr/lib/print/modelinfo
  707.     ;;
  708.     replacenet|addnet)
  709.     delete=1;
  710.     if [ "$1" = "replacenet" ]; then
  711.         delete=0
  712.     fi
  713.     #
  714.     # Add a networked printer
  715.     #
  716.     # addnet <host> <printer> <name> [<nettype>]
  717.     host=$2
  718.     printer=$3
  719.     nam=$4
  720.     type=
  721.     if [ $# -gt 4 ]; then
  722.         type="-t $5"
  723.     fi
  724.     # Install or replace the printer.  Installing a printer
  725.     # overwrites any printer or class with the same name.  It is
  726.     # the caller's responsibility to check for duplicate names.
  727.     #
  728.     # Replacing a printer changes the device and model for a
  729.         # printer, but doesn't blow away the queue.
  730.     #
  731.     if [ $delete -eq 1 ]; then
  732.         /usr/lib/lpadmin -x$nam > /dev/null 2>&1
  733.     fi
  734.  
  735.     # Unconditionally remove the Impressario stuff.  If we're replacing
  736.     # an Impressario printer with a non-Impressario printer, we need to
  737.     # do this to make sure all the extra stuff gets removed.
  738.     #
  739.     remove_impressario
  740.  
  741.     ####
  742.     # Make sure all relevant directories are available
  743.     ####
  744.     create_support_dirs
  745.  
  746.     /usr/lib/print/instnetpr $type $host $printer $nam
  747.     rc=$?
  748.     if [ $rc != 0 ]; then
  749.         exit $rc
  750.     fi
  751.     ####
  752.     # Enable the printer
  753.     ####
  754.     enable $nam > /dev/null 2>&1
  755.     /usr/lib/accept $nam > /dev/null 2>&1
  756.         selectSoloPrinterAsDefault
  757.     ;;
  758.     replace|add)
  759.     delete=1
  760.     if [ "$1" = "replace" ]; then
  761.         delete=0
  762.     fi
  763.     #
  764.     # Add a new printer
  765.     #
  766.     # add <dev> <model> <name> [OPT=xxx ...]
  767.     #
  768.     # where:
  769.     #
  770.     # <dev> is the pathname to the device
  771.     # <model> is the name of the model script to use
  772.     # <name> is the name the new printer will have
  773.     # OPT=xxx is a model modifier in which "OPT="
  774.     # lines in model are changed to "OPT=xxx".
  775.     # Multiple OPT= can be specified.
  776.     #
  777.     dev=$2
  778.     mod=$3
  779.     nam=$4
  780.     shift;shift;shift;shift
  781.     ERRNOMOD="No such printer model as \"$mod\"."
  782.     ERRNODEV="Unable to write to device \"$dev\"."
  783.     ERRNONAM="No printer name was specified."
  784.     ERRLOGIN="Logins are currently enabled on this port."
  785.     ERRMODEM="A modem is currently enabled on this port."
  786.  
  787.     # Check for existence of printer model.
  788.     #
  789.     if [ ! -r "model/${mod}" ]; then
  790.         echo $ERRNOMOD 1>&2
  791.         exit 1
  792.     fi
  793.  
  794.         # Check the ~lp/devices is created if needed. 
  795.         # Some printer drivers use this and the higher level 
  796.         # install utility is supposed to create this directory.
  797.         # Check here in case future drivers do not (easy to miss
  798.         # since most developers systems would have it and would
  799.         # assume it is a standard lp sub-dir -- it is not).
  800.         # Defensive programming.
  801.  
  802.         DIRNAME=`dirname $dev`
  803.         if [ "$DIRNAME" = "/var/spool/lp/devices" ] ; then
  804.            if [ ! -d /var/spool/lp/devices ] ; then
  805.               mkdir /var/spool/lp/devices
  806.               chmod 0755 /var/spool/lp/devices
  807.               chown lp.sys /var/spool/lp/devices
  808.            fi
  809.            if [ ! -c $dev ] ; then
  810.               mknod $dev c 1 2
  811.               chmod 0666 $dev
  812.               chown lp.sys $dev
  813.            fi
  814.         fi
  815.  
  816.     # Verify that device is there.
  817.     #
  818.     if [ ! -w $dev ]; then
  819.         echo $ERRNODEV 1>&2
  820.         exit 1
  821.     fi
  822.  
  823.     # Make sure there's a name for the new printer.
  824.     #
  825.     if [ -z "$nam" ]; then
  826.         echo $ERRNONAM 1>&2
  827.         exit 1
  828.     fi
  829.  
  830.     # Check for gettys or modems enabled if the device
  831.     # is a serial port.
  832.     #
  833.     if expr X"$dev" : ".*tty" > /dev/null; then
  834.         # Watch out for ttyd1 vs. ttym1 vs. ttyf1 etc.
  835.         #
  836.         ttynum=`expr X"$dev" : ".*tty[dmf]\([0-9]*\)"`
  837.         re="tty[dmf]$ttynum[^0-9]"
  838.         if who -l | grep $re > /dev/null; then
  839.         echo $ERRLOGIN 1>&2
  840.         exit 1
  841.         fi
  842.         ml=`grep "^[^#].*$re" /usr/lib/uucp/Devices 2> /dev/null`
  843.         if [ -n "$ml" ]; then
  844.         echo $ERRMODEM 1>&2
  845.         exit 1
  846.         fi
  847.     fi
  848.  
  849.     # Give exclusive control of device to lp
  850.     #
  851.     if [ "$dev" != "/dev/null" ]; then
  852.         chown lp  $dev
  853.         chmod 0600 $dev
  854.             # For 6.4+ update /etc/ioperms file (see ioconfig(1M))
  855.             $SETDEVPERMS -a "$dev 0600 lp sys"
  856.     fi
  857.   
  858.         # Assemble substitution arguments so they can be done in
  859.         # one sed command.
  860.  
  861.     for i
  862.     do
  863.         lhs=`expr "$i" : "\(.*\)="`
  864.         if [ -n "$lhs" ]; then
  865.         sc="${sc}-e 's@^${lhs}=.*@${i}@' "
  866.         fi
  867.     done
  868.  
  869.         # Strip out " (Impressario license required)" if found so it
  870.         # is not in the final name.  /usr/lib/print/modelinfo may add it.
  871.  
  872.         sc=`echo $sc  |  sed 's/ (Impressario license required)//'`;
  873.  
  874.         # See if we have a PPD model file.  Have to do a couple special
  875.         # steps for the PPD model driver.  We set it here so lower 
  876.         # level functions can use it.  Any ~lp/model file with the
  877.         # string "impressario_ppd_model" in the name is treated as
  878.         # a impressario PPD driver.
  879.         
  880.         test_ppd=""
  881.         HAVE_PPD=0
  882.         test_ppd=`echo $mod |  awk '/impressario_ppd_model/'`;
  883.         if [ "$test_ppd" != "" ]; then
  884.             HAVE_PPD=1
  885.         fi 
  886.  
  887.         if [ "$HAVE_PPD" = "1" ]; then
  888.             # See if this is a 3 or 4 color device being supported
  889.             # and set the global flag accordingly.  NUM_PPD_COLORS
  890.             # is used later
  891.             test_ppd=`echo $* |  awk '/numcolors=3/'`;
  892.             if [ "$test_ppd" != "" ]; then
  893.                 NUM_PPD_COLORS=3
  894.             fi
  895.             test_ppd=`echo $* |  awk '/numcolors=4/'`;
  896.             if [ "$test_ppd" != "" ]; then
  897.                 NUM_PPD_COLORS=4
  898.             fi
  899.         fi
  900.  
  901.     if [ -z "$sc" ]; then
  902.         cp model/${mod} /tmp/$nam
  903.     else
  904.         # recursive quoting in $sc requires this nastiness
  905.         #
  906.         sh -c "sed $sc model/${mod} > /tmp/$nam"
  907.     fi
  908.  
  909.     # We don't want any partial adds
  910.     #
  911.     trap '' 1 2 3 15
  912.  
  913.     # Install or replace the printer.  Installing a printer
  914.     # overwrites any printer or class with the same name.  It is
  915.     # the caller's responsibility to check for duplicate names.
  916.     #
  917.     # Replacing a printer changes the device and model for a
  918.         # printer, but doesn't blow away the queue.
  919.     #
  920.     if [ $delete -eq 1 ]; then
  921.         /usr/lib/lpadmin -x$nam > /dev/null 2>&1
  922.     fi
  923.  
  924.     # Unconditionally remove the Impressario stuff.  If we're replacing
  925.     # an Impressario printer with a non-Impressario printer, we need to
  926.     # do this to make sure all the extra stuff gets removed.
  927.     #
  928.     remove_impressario
  929.  
  930.     /usr/lib/lpadmin -p$nam -v$dev -i/tmp/$nam
  931.     rc=$?
  932.     rm -f /tmp/$nam
  933.     if [ $rc != 0 ]; then
  934.         remove_printer $nam  # No partial printers!!
  935.         exit 1
  936.     fi
  937.     df=`cat $SPOOL_DIR/default 2> /dev/null`
  938.     if [ -z "$df" ]; then
  939.         /usr/lib/lpadmin -d$nam
  940.     fi
  941.     enable $nam > /dev/null 2>&1
  942.  
  943.     # Enable the printer
  944.     #
  945.     /usr/lib/accept $nam > /dev/null 2>&1
  946.         selectSoloPrinterAsDefault
  947.  
  948.     # Install all the Impressario support
  949.     #
  950.     RTYPE=`egrep "^TYPE=" $SPOOL_DIR/interface/$nam`
  951.     rt="`echo "$RTYPE" | sed 's/TYPE=//'`"
  952.      RHOST=`egrep "^HOSTNAME=" $SPOOL_DIR/interface/$nam`
  953.      rh="`echo "$RHOST" | sed 's/HOSTNAME=//'`"
  954.      RPRTR=`egrep "^HOSTPRINTER=" $SPOOL_DIR/interface/$nam`
  955.     rp="`echo "$RPRTR" | sed 's/HOSTPRINTER=//'`"
  956.  
  957.         PPDNAME=`egrep "^ppdname=" $SPOOL_DIR/interface/$nam`
  958.         ppd_name="`echo "$PPDNAME" | sed 's/ppdname=//'`"
  959.  
  960.     #
  961.     # Always call this routine last, it has side effects
  962.     #
  963.     install_impressario
  964.     exit 0
  965.     ;;
  966.     remove)
  967.     #
  968.     # lputil remove <printer or class> <move dest>
  969.     #
  970.     # remove a printer after optionally moving all of its
  971.     # outstanding requests to another destination.
  972.     #
  973.     nam=$2
  974.     mvdest=$3
  975.     if [ -z "$nam" ]; then
  976.         echo "No printer name was specified to delete." 1>&2
  977.         exit 2
  978.     fi
  979.  
  980.     # We don't want any partial deletes
  981.     #
  982.     trap '' 1 2 3 15
  983.  
  984.     # Close off both ends of the print queue
  985.     #
  986.     /usr/lib/reject -r"*deletion in progress*" $nam > /dev/null 2>&1
  987.     disable -c -r"*deletion in progress*" $nam > /dev/null 2>&1
  988.  
  989.     # Move queue if needed
  990.     #
  991.     if [ -n "$mvdest" ]; then
  992.         /usr/lib/lpmove $nam $mvdest > /dev/null 2>&1
  993.     fi
  994.  
  995.     remove_printer $nam
  996.     exit 0
  997.     ;;
  998.     chkremote)
  999.     #
  1000.     # lputil chkremote <machine> <remote login id>
  1001.     #
  1002.     # chkremote will list the printers on a remote host.
  1003.     #
  1004.     if /sbin/chkconfig network; then
  1005.         :
  1006.     else
  1007.         echo "Networking has not been enabled on this system." 1>&2
  1008.         exit 1
  1009.     fi
  1010.     if [ -z "$2" ]; then
  1011.         echo "No remote hostname was specified for chkremote." 1>&2
  1012.         exit 2
  1013.     fi
  1014.  
  1015.     /usr/lib/print/listprinters -a $2 2>/dev/null
  1016.     rcexit
  1017.     exit 0
  1018.     ;;
  1019.     remoteinfo)
  1020.     #
  1021.     # lputil remoteinfo <machine> <printer> <login id>
  1022.     #
  1023.     # Get the information associated with a printer located
  1024.     # on a remote machine.
  1025.     #
  1026.     if [ -z "$4" ]; then
  1027.         REMOTE_LOGIN_ID=lp
  1028.     else
  1029.         REMOTE_LOGIN_ID=$4
  1030.     fi
  1031.     NAME=
  1032.     TYPE=
  1033.     HOSTNAME=
  1034.     HOSTPRINTER=
  1035.     BAUDRATE=
  1036.     STTYPARAMS=
  1037.     eval `rsh $2 -n -l $REMOTE_LOGIN_ID \
  1038.             "/bin/sh -c \"/usr/lib/lputil getinfo $3\"" 2>/dev/null` \
  1039.             2> /dev/null 1>&2 0<&1
  1040.  
  1041.     # If we don't come up with all of the keywords, we can
  1042.     # try to guess on some.
  1043.     #
  1044.     if [ -z "$TYPE" ]; then
  1045.         ps=`rsh $2 -n -l $REMOTE_LOGIN_ID \
  1046.             "/bin/sh -c \"grep PostScript \
  1047.             $OLD_SPOOL_DIR/interface/$3 2>/dev/null\""`
  1048.         if [ -n "$ps" ]; then
  1049.         NAME="LaserWriter"
  1050.         TYPE=PostScript
  1051.         else
  1052.         color=`rsh $2 -n -l $REMOTE_LOGIN_ID \
  1053.                     "/bin/sh -c \"grep 'color printer' \
  1054.                     $OLD_SPOOL_DIR/interface/$3 2>/dev/null\""`
  1055.         if [ -n "$color" ]; then
  1056.             NAME="Color Printer"
  1057.             TYPE=Color
  1058.         fi
  1059.         fi
  1060.     fi
  1061.     if [ -z "$HOSTNAME" -a -n "$host" ]; then
  1062.         HOSTNAME=$host
  1063.     fi
  1064.     if [ -z "$HOSTPRINTER" -a -n "$printer" ]; then
  1065.         HOSTPRINTER=$printer
  1066.     fi
  1067.     echo NAME=\"$NAME\"
  1068.     echo TYPE=$TYPE
  1069.     echo HOSTNAME=$HOSTNAME
  1070.     echo HOSTPRINTER=$HOSTPRINTER
  1071.     echo BAUDRATE=$BAUDRATE
  1072.     echo STTYPARAMS=$STTYPARAMS
  1073.     exit 0
  1074.     ;;
  1075.     printq)
  1076.     #
  1077.     # lputil printq <machine> <printer> <login id>
  1078.     #
  1079.     # printq will return the lpstat information from
  1080.     # a local or remote print queue
  1081.     #
  1082.     if [ -z "$2" -o "`hostname`" = "$2" ]; then
  1083.         /usr/bin/lpstat -o$3 2> /dev/null 2>&1
  1084.         exit 3
  1085.     fi
  1086.     if [ -z "$4" ]; then
  1087.         REMOTE_LOGIN_ID=lp
  1088.     else
  1089.         REMOTE_LOGIN_ID=$4
  1090.     fi
  1091.     if /sbin/chkconfig network; then
  1092.         :
  1093.     else
  1094.         echo "Networking has not been enabled on this system." 1>&2
  1095.         exit 1
  1096.     fi
  1097.     rsh $2 -n -l $REMOTE_LOGIN_ID \
  1098.         "/bin/sh -c \"/usr/bin/lpstat -o$3 2> /dev/null\"" 2>&1
  1099.     exit $?
  1100.     ;;
  1101.     *)
  1102.     echo "lputil: invalid operation - $*" 1>&2
  1103.     exit 2
  1104.     ;;
  1105. esac
  1106.  
  1107. #
  1108. # Return a successful exit code
  1109. #
  1110. exit 0
  1111.